#pragma once

#include <type_traits>
#include <cstddef>
#include <cmath>

namespace mdtx::online
{
    namespace detail
    {
        template <typename Time>
        struct duration_type_impl
        {
            using type = decltype(std::declval<Time>() - std::declval<Time>());
        };
    } // namespace detail

    template <typename Time>
    using duration_type_t = typename detail::duration_type_impl<Time>::type;

    template <typename Time, typename Duration>
    inline Time align_window_start(Time time, Duration window, Time epoch = Time{})
    {
        Duration dt = time - epoch;
        if constexpr (std::is_floating_point_v<Duration>)
        {
            // for R compatibility: POSIXct is represented by double
            dt = std::fmod(dt, window);
        }
        else
        {
            dt = dt % window;
        }
        return time - dt;
    }
}
